/************************************************************************
  * Copyright(c) 2023 Levetop Semiconductor Co.,Led. All rights reserved.
  * @file     iic.c
  * @author   UartTFT Application Team
  * @version  V0.0.1
  * @date     2023-01-01
  * @brief    
 *************************************************************************/

#include "iic.h"

#define TIMEOUT 50000
#define hwI2C0_Device_Addr 0x28

extern uint8_t bI2C0_TxM_Data[16];
extern uint8_t bI2C0_RxM_Data[128];
uint8_t IIC_Buf[128];

uint32_t  len, u32Tmp;
uint8_t tmpID, tmpEvent;
uint32_t u16Tmp, tmpX, tmpY;
uint16_t tpX[10], tpY[10];
uint32_t TPmaxX, TPmaxY;
uint8_t tpActive;

void i2c_delay(uint8_t us)
{
	uint8_t i;
	for (i = 0; i < us; i++)
		asm("NOP");
	// asm("NOP");
	// for(i=0;i<us;i++)asm("NOP");
	// for(i=0;i<us;i++)asm("NOP");
}

//-----------------------------------------------------------------------------
void I2cInit(void)
{
//	I2C_ConfigGpio(I2C1, I2C_SDA, GPIO_OUTPUT);
//	I2C_ConfigGpio(I2C1, I2C_SCL, GPIO_OUTPUT);
//	SPI_ConfigGpio(SPI3, SPI_SS, GPIO_OUTPUT);
//
//	EPORT_ConfigGpio(EPORT_PIN4, GPIO_INPUT);
}

void i2c_sda_output(void)
{
//	I2C_ConfigGpio(I2C1, I2C_SDA, GPIO_OUTPUT);
}

void i2c_sda_input(void)
{
//	I2C_ConfigGpio(I2C1, I2C_SDA, GPIO_INPUT);
}

void i2c_set_scl(uint8_t index)
{
//	if (index)
//		I2C_WriteGpioData(I2C1, I2C_SCL, 1);
//	else
//		I2C_WriteGpioData(I2C1, I2C_SCL, 0);
}

void i2c_set_sda(uint8_t index)
{
//	if (index)
//		I2C_WriteGpioData(I2C1, I2C_SDA, 1);
//	else
//		I2C_WriteGpioData(I2C1, I2C_SDA, 0);
}

uint8_t i2c_get_sda(void)
{
//	if (I2C_ReadGpioData(I2C1, I2C_SDA))
//		return 1;
//	else
//		return 0;
}

void i2c_start(void)
{
	i2c_sda_output();
	i2c_set_sda(1);
	i2c_set_scl(1);
	DelayUS(20);
	i2c_set_sda(0);
	DelayUS(2);
	i2c_set_scl(0);
	DelayUS(2);
}

void i2c_stop(void)
{
	i2c_sda_output();
	i2c_set_scl(0);
	i2c_set_sda(0);
	i2c_set_scl(1);
	DelayUS(2);
	i2c_set_sda(1);
	DelayUS(2);
}

uint8_t i2c_write(uint8_t value)
{
	uint8_t i, j, ack;

	i2c_sda_output();
	i2c_set_scl(0);
	for (i = 0; i < 8; i++)
	{
		if (value & 0x80)
			i2c_set_sda(1);
		else
			i2c_set_sda(0);

		DelayUS(2);
		i2c_set_scl(1);
		DelayUS(3);
		i2c_set_scl(0);
		value = value << 1;
	}
	i2c_sda_input();
	DelayUS(20);
	i2c_set_scl(1);
	DelayUS(1);
	ack = i2c_get_sda();
	i2c_set_scl(0);

	return ack;
}

uint8_t i2c_read(uint8_t ack)
{
	uint8_t i, j, u8Tmp;

	i2c_sda_input();
	u8Tmp = 0x00;
	for (i = 0; i < 8; i++)
	{
		u8Tmp = u8Tmp << 1;

		i2c_set_scl(0);
		DelayUS(3);
		i2c_set_scl(1);
		DelayUS(2);
		if (i2c_get_sda())
			u8Tmp |= 0x01;
	}

	i2c_set_scl(0);
	i2c_sda_output();

	if (ack)
		i2c_set_sda(0);
	else
		i2c_set_sda(1);

	// I2C->U8I2CPDR.SDA = ack;
	DelayUS(20);
	i2c_set_scl(1);
	DelayUS(2);
	i2c_set_scl(0);

	return u8Tmp;
}



#if (UARTBUS_OPTION == 3)

#include "bsp.h"

void I2C_Slave_TEST(uint8_t sla_addr)
{
	I2C->CR = 0x0;
	I2C->CR |= CR_EN;

	delay(100);

	I2C->CR |= CR_ACKEN;

	I2C->CR |= CR_IEN;
	I2C->CR &= ~CR_MSMOD;

	I2C->SAHR = sla_addr << 1;
	/*Configure interrupts in slave mode*/
	NVIC_Init(3, 3, I2C_1_IRQn, 2);
}

uint16_t Rx_len = 0, Tx_len = 0;
uint16_t reg_addr = 0;
uint8_t flag_IIC_REG[20];
uint16_t ID_IIC_WAV = 0;

// IIC slave transceiver interrupt function
void I2C1_IRQHandler(void)
{
	volatile uint8_t tmp = 0;
	static uint16_t curve_rev_val = 0;
	static uint8_t curve_rev_num = 0;
	static uint8_t curve_rev_tmp = 0;
	static uint16_t curve_rev_data = 0;
	static uint8_t curve_rev_cnt = 0;

	uint8_t i = 0;

	uint8_t i2c_status, i2c_hs_status;

	i2c_status = I2C->CSR;
	i2c_hs_status = I2C->SHSIR;

	if ((i2c_hs_status & SLV_HS) != SLV_HS)
	{
		if ((i2c_status & SR_AASLV) == SR_AASLV) // The current slave device is addressed by master  Slave address matching
		{
			I2C->CR &= ~CR_AMIE;			   // Under normal circumstances, turn off the slave address matching interrupt
			if ((i2c_status & SR_RC) == SR_RC) // Receiving is interrupted. The received address and data will come in
			{
				Tx_len = 0;
				if ((I2C->CSR & SR_TF) == SR_TF) // Transmission completion interrupt
				{
					if (Rx_len == 0) // Upper 8 bits of receiving address
					{
						reg_addr = I2C->CDR;
					}
					else if (Rx_len == 1) // Lower 8 bits of receiving address
					{
						reg_addr = (reg_addr << 8) | I2C->CDR;

						Var_AddrRemapping(&reg_addr);
						if (reg_addr >= 0xC001 && reg_addr <= 0xCFFF) // Judge whether it is the curve buffer address, special processing
						{
							curve_rev_val = reg_addr & 0xFFF;
							curve_rev_cnt = 0;
							curve_rev_num = 0;
							for (i = 0; i < CURVE_SIZE; i++)
							{
								if (curve_rev_val & (1 << i))
									curve_rev_num++; // Record how many groups of channels
							}
						}
					}
					else // receive data
					{
						if (reg_addr <= VAR_REG_S) // In the variable area
						{
							// Direct saving of variable data
							var[2 * reg_addr + Rx_len - 2] = I2C->CDR;
						}
						else if (reg_addr >= 0x7000 && reg_addr <= 0x71FF) // Register region
						{
							// WAV register data needs special processing
							if (2 * reg_addr + Rx_len - 2 == 2 * 0x700a)
							{
								ID_IIC_WAV = I2C->CDR;
							}
							else if (2 * reg_addr + Rx_len - 2 == 2 * 0x700a + 1)
							{
								ID_IIC_WAV = (ID_IIC_WAV << 8) | I2C->CDR;
							}
							// The remaining register data is saved directly
							else
							{
								var[2 * reg_addr + Rx_len - 2] = I2C->CDR;
							}

							if (Rx_len % 2) // The update flag of the corresponding register will be triggered every time 2Bytes are received
							{
								flag_IIC_REG[(2 * (reg_addr - 0x7000) + Rx_len - 2) / 2] = 1;
							}
						}
						else if (reg_addr >= 0xC001 && reg_addr <= 0xCFFF) // Curve channel write data
						{
							for (i = curve_rev_cnt; i < CURVE_SIZE; i++)
							{
								if (curve_rev_val & (1 << i)) // Poll to detect whether 8 channels have triggered updates
								{
									if (Rx_len % 2 == 0)
									{
										curve_rev_data = (I2C->CDR) << 8; // Receive the first byte of curve data
									}
									else if (Rx_len % 2 == 1)
									{
										Curve_buff[i][Curve_count[i]] = curve_rev_data | (I2C->CDR); // Receive the second byte of curve data
										Curve_count[i]++;
										if (Curve_count[i] >= 1024)
										{
											Curve_count[i] = 0;
										}
										curve_update_flag[i] = 1;

										curve_rev_cnt++;
										if (curve_rev_cnt >= curve_rev_num)
											curve_rev_cnt = 0;
									}
									break;
								}
							}
						}
						else // Other addresses only receive but do not process
						{
							i = I2C->CDR;
						}
					}

					Rx_len++;
					I2C->CR |= CR_ACKEN;
				}
				else // Received address
				{
					Rx_len = 0;
					I2C->CR |= CR_ACKEN;
				}
			}
			else // No receive interrupt, read signal received
			{
				if ((i2c_status & SR_TF) == SR_TF) // Transmission completion interrupt
				{
					Rx_len = 0;
					if ((i2c_status & SR_DACK) == SR_DACK)
					{
						// Direct feedback data
						if (reg_addr <= 0x6FFF) // In the variable area
						{
							I2C->CDR = var[2 * reg_addr + Tx_len];
						}
						else if (reg_addr >= 0x7000 && reg_addr <= 0x71FF) // In register area
						{
							I2C->CDR = var[2 * reg_addr + Tx_len];
						}
						else
						{
							I2C->CDR = 0xFF;
						}

						Tx_len++;
					}
					else
					{
						tmp = I2C->CDR;
						tmp++; // add for warning
					}
				}
				else
				{
					;
				}
			}
		}
		else
		{
			// asm("bkpt");
		}
	}
	else
	{
		I2C->SSHTR = (I2C->SSHTR & 0xc0) | 0x1;
		I2C->SSHTR = I2C->SSHTR | 0x1;

		I2C->SHSIR |= SLV_HS;
	}
}
#endif
